/*
 * Copyright (C) 2011 Dirk Weißenborn, dirk.weissenborn@gmail.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.weissenborn.colabtex.client.activities;

import java.util.Map;

import com.weissenborn.colabtex.client.ClientFactory;
import com.weissenborn.colabtex.client.events.GroupRemovedEvent;
import com.weissenborn.colabtex.client.events.PadCreatedEvent;
import com.weissenborn.colabtex.client.events.PadRemovedEvent;
import com.weissenborn.colabtex.client.events.UserUpdatedEvent;
import com.weissenborn.colabtex.client.events.UserUpdatedEventHandler;
import com.weissenborn.colabtex.client.places.Dashboard;
import com.weissenborn.colabtex.client.service.EtherpadService;
import com.weissenborn.colabtex.client.service.EtherpadServiceAsync;
import com.weissenborn.colabtex.client.view.GroupManagerView;

import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.Place;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AcceptsOneWidget;

/**
 * The Class GroupManagerActivity which controls the view of the grouop management
 */
public class GroupManagerActivity extends AbstractActivity implements GroupManagerView.Presenter {
	
	/** The client factory. */
	private ClientFactory clientFactory;
	
	/** The view. */
	private final GroupManagerView view;
	
	/**
	 * Instantiates a new group manager activity.
	 *
	 * @param clientFactory the client factory
	 */
	public GroupManagerActivity(ClientFactory clientFactory) {
		this.clientFactory = clientFactory;
		view = clientFactory.getGroupManagerView();
	}

	/* (non-Javadoc)
	 * @see com.google.gwt.activity.shared.Activity#start(com.google.gwt.user.client.ui.AcceptsOneWidget, com.google.gwt.event.shared.EventBus)
	 */
	public void start(AcceptsOneWidget containerWidget, EventBus eventBus) {	
		view.setPresenter(this);
		
		fillGroups();
		fillMembers();
		fillPads();		
		
		eventBus.addHandler(UserUpdatedEvent.TYPE, new UserUpdatedEventHandler() {
			public void onUserUpdated(UserUpdatedEvent event) {
				fillGroups();
				fillMembers();
				fillPads();
			}
		});
		
		containerWidget.setWidget(view.asWidget());
	}

	/* (non-Javadoc)
	 * @see com.weissenborn.colabtex.client.view.GroupManagerView.Presenter#fillMembers()
	 */
	public void fillMembers() {
		view.getMemberList().clear();
		
		EtherpadServiceAsync service = EtherpadService.Util.getInstance();
		AsyncCallback<Map<String, String>> callback = new AsyncCallback<Map<String,String>>() {	
			public void onSuccess(Map<String, String> result) {
				for (String key : result.keySet()) {
					view.getMemberList().addItem(key+"~"+result.get(key));
				}
			}
			
			public void onFailure(Throwable caught) {
				Window.alert("No connection to server");
			}
		};
		service.listMembers(view.getGroupName(), callback);
				
	}

	/**
	 * Fill groups.
	 */
	public void fillGroups() {
		view.getGroupNameBox().clear();
		for (String group : clientFactory.getUser().getPermissions().keySet()) {
			if(clientFactory.getUser().getPermissions().get(group).equalsIgnoreCase("Admin"))
				view.getGroupNameBox().addItem(group);
		}
	}
	
	/* (non-Javadoc)
	 * @see com.weissenborn.colabtex.client.view.GroupManagerView.Presenter#fillPads()
	 */
	public void fillPads() {
		final String group = view.getGroupName();	
		view.getPadList().clear();
		if(group == null)
			return;
		EtherpadServiceAsync service = EtherpadService.Util.getInstance();
		AsyncCallback<Map<String, String>> callback = new AsyncCallback<Map<String,String>>() {	
			public void onSuccess(Map<String, String> result) {
				for (String padName : result.keySet()) {
					view.getPadList().addItem(padName.substring(padName.indexOf("$")+1));
				}
			}
			
			public void onFailure(Throwable caught) {
				Window.alert("No connection to server");
			}
		};
		service.listPads(clientFactory.getUser().getPermissions().get(group),group, callback);
	}

	/* (non-Javadoc)
	 * @see com.weissenborn.colabtex.client.view.GroupManagerView.Presenter#goTo(com.google.gwt.place.shared.Place)
	 */
	public void goTo(Place place) {
		clientFactory.getPlaceController().goTo(place);
	}

	/* (non-Javadoc)
	 * @see com.weissenborn.colabtex.client.view.GroupManagerView.Presenter#deleteGroup(com.weissenborn.colabtex.client.view.GroupManagerView)
	 */
	public void deleteGroup() {
		final GroupManagerView view = clientFactory.getGroupManagerView();
		
		final EtherpadServiceAsync service = EtherpadService.Util.getInstance();
		AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
			public void onSuccess(Boolean result) {
				Window.alert("Successfully removed group!");
				clientFactory.getEventBus().fireEvent(new GroupRemovedEvent(view.getGroupName()));
				goTo(new Dashboard());
			}
			
			public void onFailure(Throwable caught) {
				Window.alert(caught.getMessage());
			}
		};
		service.deleteGroup(view.getGroupName(), callback);
	}

	/* (non-Javadoc)
	 * @see com.weissenborn.colabtex.client.view.GroupManagerView.Presenter#addGroupPad(com.weissenborn.colabtex.client.view.GroupManagerView)
	 */
	public void addGroupPad() {
		final GroupManagerView view = clientFactory.getGroupManagerView();
		
		if(view.getPadName().isEmpty())
			return;
		
		final EtherpadServiceAsync service = EtherpadService.Util.getInstance();
		AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
			public void onSuccess(Boolean result) {
				if(result) {
					Window.alert("Successfully added Pad!");
					clientFactory.getEventBus().fireEvent(new PadCreatedEvent(view.getPadName(), view.getGroupName()));
					view.getPadList().addItem(view.getPadName());
				}
				else 
					Window.alert("Failure adding pad! Could it be that it already exists? Try another name!");
			}
			
			public void onFailure(Throwable caught) {
				Window.alert(caught.getMessage());
			}
		};
		
		service.createGroupPad(view.getGroupName(), view.getPadName(), callback);
	}

	/* (non-Javadoc)
	 * @see com.weissenborn.colabtex.client.view.GroupManagerView.Presenter#addMember(java.lang.String, java.lang.String, java.lang.String)
	 */
	public void addMember(final String member, final String role, String groupName) {
		EtherpadServiceAsync service = EtherpadService.Util.getInstance();
		
		AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
			public void onSuccess(Boolean result) {
				if(result) {
					Window.alert("Successfully added Member!");
					view.addMember(member, role);
				}
				else
					Window.alert("Problem when adding Member! Could be that no such user exists!?");
			}
			
			public void onFailure(Throwable caught) {
				Window.alert(caught.getMessage());				
			}
		};
		
		service.addPermission(groupName, member, role, callback);
	}

	/* (non-Javadoc)
	 * @see com.weissenborn.colabtex.client.view.GroupManagerView.Presenter#deleteMember(java.lang.String, java.lang.String)
	 */
	public void deleteMember(final String name, String groupName) {
		EtherpadServiceAsync service = EtherpadService.Util.getInstance();
		
		AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
			public void onSuccess(Boolean result) {
				if(result) {
					Window.alert("Successfully removed Member!");
					view.deleteMember(name);
				}
				else
					Window.alert("You can't remove this member because he is also admin!");
			}
			
			public void onFailure(Throwable caught) {
				Window.alert(caught.getMessage());								
			}
		};
		
		service.removePermission(groupName, name, false, callback);
	}

	/* (non-Javadoc)
	 * @see com.weissenborn.colabtex.client.view.GroupManagerView.Presenter#deleteGroupPad(java.lang.String, java.lang.String)
	 */
	public void deleteGroupPad(final String padName, String groupName) {
		EtherpadServiceAsync service = EtherpadService.Util.getInstance();

		AsyncCallback<Void> callback = new AsyncCallback<Void>() {
			public void onSuccess(Void result) {
				Window.alert("Successfully removed pad!");
				clientFactory.getEventBus().fireEvent(new PadRemovedEvent(padName, view.getGroupName()));
			}
			
			public void onFailure(Throwable caught) {
				Window.alert(caught.getMessage());	
			}
		};
		
		service.deleteGroupPad(groupName, padName, callback);
	}
}
